from django.db import models
from django.core.validators import RegexValidator


# Create your models here.

class ActiveBaseModel(models.Model):
    active = models.SmallIntegerField(verbose_name='状态', choices=(('0', '删除'), ('1', '活动')), default=1)

    class Meta:
        abstract = True


class Users(ActiveBaseModel):
    """
    用户表
    """
    role = models.SmallIntegerField(verbose_name='用户角色', choices=((1, '管理员'), (2, '安全运营'), (3, '普通用户')))
    username = models.CharField(verbose_name='用户名', max_length=64, db_index=True)
    nickname = models.CharField(verbose_name='姓名', max_length=64)
    # password = models.CharField(verbose_name='密码', max_length=32, validators=[
    #     RegexValidator(regex=r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$',
    #                    message='密码必须包含大小写、字母和数字，长度至少8位')])

    password = models.CharField(verbose_name='密码', max_length=32, )

    def __str__(self):
        return self.username


class DeviceType(models.Model):
    """
    安全设备类型表
    """
    title = models.CharField(verbose_name='安全设备类型', max_length=16, unique=True)

    def __str__(self):
        return self.title


#
class Vendor(models.Model):
    """
    设备厂商
    """
    title = models.CharField(verbose_name='厂商', max_length=16, unique=True)

    def __str__(self):
        return self.title


class Device(ActiveBaseModel):
    """
    安全设备表
    """
    title = models.CharField(verbose_name='设备名称', max_length=128)
    device_type = models.ForeignKey(verbose_name='设备类型', to=DeviceType, on_delete=models.CASCADE)
    vendor = models.ForeignKey(verbose_name='厂商', to=Vendor, on_delete=models.CASCADE)

    url = models.URLField(verbose_name='设备访问地址', db_index=True)
    color_choices = (
        (1, "#56b8eb"),
        (2, "#f28033"),
        (3, "#ebc656"),
        (4, "#a2d148"),
        (5, "#20BFA4"),
        (6, "#7461c2"),
        (7, "#20bfa3"),
    )
    color = models.SmallIntegerField(verbose_name='颜色', choices=color_choices, default=1)
    desc = models.TextField(verbose_name='设备描述', null=True, blank=True)

    def __str__(self):
        return self.title


class K01(models.Model):
    """
    威胁情报联防阻断k01攻击数据统计
    """
    atk_count = models.IntegerField(verbose_name='攻击数量')
    atkip_count = models.IntegerField(verbose_name='攻击IP数量')
    outgoing_count = models.IntegerField(verbose_name='外联数量')
    create_datetime = models.DateTimeField(verbose_name='创建日期')
    update_datetime = models.DateTimeField(verbose_name='更新日期', auto_now=True, db_index=True)


class K01AttackIp(models.Model):
    """
    k01攻击IP
    """
    sip = models.CharField(verbose_name='源IP', max_length=32)
    dip = models.CharField(verbose_name='目标IP', max_length=32)
    dpt = models.CharField(verbose_name='目标端口', max_length=16)
    atknum = models.IntegerField(verbose_name='攻击次数')
    cet_atksvr_num = models.IntegerField(verbose_name='被攻击IP数量')
    last_atk_svr = models.CharField(verbose_name='最近攻击单位', max_length=64)
    last_atk_time = models.DateTimeField(verbose_name='最近攻击时间')
    sga = models.CharField(verbose_name='归属地', max_length=64)
    ioc_type = models.CharField(verbose_name='情报类型', max_length=64)
    create_datetime = models.DateTimeField(verbose_name='创建日期')


class Botgate(models.Model):
    request_count = models.IntegerField(verbose_name='总请求数', default=0)
    abnormal_request_count = models.IntegerField(verbose_name='异常请求数', default=0)
    high_warning_count = models.IntegerField(verbose_name='高风险告警事件数', default=0)
    middle_warning_count = models.IntegerField(verbose_name='中风险告警事件数', default=0)
    low_warning_count = models.IntegerField(verbose_name='低风险告警事件数', default=0)
    ubb_count = models.IntegerField(verbose_name='攻防对抗策略', default=0)
    replay_attack_count = models.IntegerField(verbose_name='重放攻击', default=0)
    no_cookie_count = models.IntegerField(verbose_name='简单脚本攻击', default=0)
    invalid_token_count = models.IntegerField(verbose_name='令牌篡改', default=0)
    bot_count = models.IntegerField(verbose_name='高级自动化工具', default=0)
    inject_high_count = models.IntegerField(verbose_name='漏洞攻击(高风险)', default=0)
    inject_middle_count = models.IntegerField(verbose_name='漏洞攻击(中风险）', default=0)
    inject_low_count = models.IntegerField(verbose_name='漏洞攻击(低风险）', default=0)
    nday_count = models.IntegerField(verbose_name='Nday事件', default=0)
    scan_count = models.IntegerField(verbose_name='扫描总数', default=0)
    scan_ip_count = models.IntegerField(verbose_name='扫描IP数', default=0)
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)

    def total_warning_count(self):
        """获取告警事件总数"""
        return self.high_warning_count + self.middle_warning_count + self.low_warning_count

    def total_inject_count(self):
        """获取漏洞攻击总数"""
        return self.inject_high_count + self.inject_middle_count + self.inject_low_count

    def normal_request_count(self):
        """获取正常请求数"""
        return self.request_count - self.abnormal_request_count


class BotgateWebSiteRequest(models.Model):
    """
    站点请求列表
    """
    request_type_choices = (
        (1, '正常请求'),
        (2, '异常请求'),
    )
    request_type = models.SmallIntegerField(verbose_name='请求类型', choices=request_type_choices)
    website = models.CharField(verbose_name='站点名称', max_length=64)
    request_count = models.IntegerField(verbose_name='请求次数')
    bandwidth = models.DecimalField(verbose_name='占用带宽(MB)', default=0, max_digits=10, decimal_places=2)
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class BotgateAttackIp(models.Model):
    """
    恶意IP表
    """
    src_ip = models.GenericIPAddressField(verbose_name='攻击IP')
    location = models.CharField(verbose_name='来源区域', max_length=64, null=True, blank=True)
    attack_count = models.IntegerField(verbose_name='攻击总数', default=0)
    no_cookie_count = models.IntegerField(verbose_name='简单脚本攻击', default=0)
    replay_attack_count = models.IntegerField(verbose_name='重放攻击', default=0)
    bot_attack_count = models.IntegerField(verbose_name='高级自动化工具攻击', default=0)
    inject_attack_count = models.IntegerField(verbose_name='漏洞攻击', default=0)
    nday_name_count = models.IntegerField(verbose_name='Nday类型数', default=0)
    nday_count = models.IntegerField(verbose_name='Nday攻击数', default=0)
    scan_count = models.IntegerField(verbose_name='扫描次数', default=0)
    high_risk_count = models.IntegerField(verbose_name='高风险报警', default=0)
    middle_risk_count = models.IntegerField(verbose_name='中风险告警', default=0)
    low_risk_count = models.IntegerField(verbose_name='低风险告警', default=0)
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)

    def total_risk_count(self):
        """
        获取安全事件总数
        """
        return self.high_risk_count + self.middle_risk_count + self.low_risk_count


class BotgateAttackPath(models.Model):
    """
    攻击路径统计
    """
    path = models.CharField(verbose_name='攻击路径', max_length=128)
    attack_count = models.IntegerField(verbose_name='攻击次数')
    hostname = models.CharField(verbose_name='站点名称', max_length=128)
    server_alias = models.CharField(verbose_name='站点名称', max_length=128)
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class BotgateAttackType(models.Model):
    """
    攻击类型统计
    """
    attack_type = models.CharField(verbose_name='攻击类型', max_length=16)
    attack_count = models.IntegerField(verbose_name='攻击数量')
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class BotgateBotType(models.Model):
    """
    高级自动化工具
    """
    bot_type = models.CharField(verbose_name='高级自动化工具', max_length=32)
    bot_attack_count = models.IntegerField(verbose_name='攻击数量')
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class BotgateInjectAttackType(models.Model):
    """
    漏洞攻击类型
    """
    attack_type = models.CharField(verbose_name='攻击类型', max_length=16)
    attack_count = models.IntegerField(verbose_name='攻击数量')
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class BotgateNdayType(models.Model):
    """
    Nday攻击类型统计
    """
    nday_name = models.CharField(verbose_name='Nday名称', max_length=128)
    nday_attack_count = models.IntegerField(verbose_name='攻击数量')
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class BotgateWarnLog(models.Model):
    """
    告警事件
    """
    risk_level_choices = (
        (1, '高风险'),
        (2, '中风险'),
        (3, '低风险'),
    )
    risk_level = models.SmallIntegerField(verbose_name='风险级别', choices=risk_level_choices)
    warning = models.CharField(verbose_name='告警事件名称', max_length=128)
    warning_count = models.IntegerField(verbose_name='告警数量', default=0)
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class QiAnXingFW(models.Model):
    """
    奇安信防火墙统计数据
    """
    permit_count = models.IntegerField(verbose_name='允许通过总数')
    deny_count = models.IntegerField(verbose_name='拒绝通过总数数')
    create_date = models.DateTimeField(verbose_name='采集时间', auto_now_add=True)
    current_permit_count = models.IntegerField(verbose_name='当前允许通过数')
    current_deny_count = models.IntegerField(verbose_name='当前拒绝通过数')


class SangforFw(models.Model):
    """
    深信服防火墙统计
    """
    attack_count = models.IntegerField(verbose_name='攻击次数')
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)


class SangforFwAttackLog(models.Model):
    """
    深信服防火墙
    """
    attack_type = models.CharField(verbose_name='威胁类型', max_length=64)
    src_ip = models.CharField(verbose_name='源IP', max_length=32)
    src_port = models.CharField(verbose_name='源端口', max_length=16)
    src_ip_addr = models.CharField(verbose_name='源IP归属地', max_length=64, null=True)
    dst_ip = models.CharField(verbose_name='目的IP地址', max_length=32)
    dst_port = models.CharField(verbose_name='目的端口', max_length=16)
    protocol = models.CharField(verbose_name='协议', max_length=16)
    level_choices = (
        (0, '致命'),
        (1, '高危'),
        (2, '中危'),
        (3, '低危'),
        (4, '信息')
    )
    level = models.SmallIntegerField(verbose_name='严重等级', choices=level_choices)
    net_action_choices = (
        (1, '允许'),
        (2, '拒绝')
    )
    net_action = models.SmallIntegerField(verbose_name='动作', choices=net_action_choices)
    record_time = models.DateTimeField(verbose_name='时间')
    create_datetime = models.DateTimeField(verbose_name='创建时间')


class BlockIp(models.Model):
    """
    封锁IP列表
    """
    src_ip = models.GenericIPAddressField(verbose_name='恶意IP')
    location = models.CharField(verbose_name='来源区域', max_length=64, null=True, blank=True)
    block_device_choices = (
        ('botgate', '瑞数动态防御系统'),
        ('sangfor_fw', '深信服防火墙')
    )
    block_device = models.CharField(verbose_name='封禁设备', choices=block_device_choices, max_length=16)
    block_type_choices = (
        (1, '手动'),
        (2, '自动')
    )

    block_type = models.IntegerField(verbose_name='封锁类型', choices=block_type_choices)
    status_choices = (
        (0, "解封"),
        (1, "封禁")
    )
    status = models.SmallIntegerField(verbose_name='IP状态', choices=status_choices)
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    block_datetime = models.DateTimeField(verbose_name='封禁时间')
    unblock_datetime = models.DateTimeField(verbose_name='解封时间')
    create_user = models.ForeignKey(verbose_name='操作人', to=Users, on_delete=models.CASCADE)


class SkyEye(models.Model):
    """
    天眼报警数统计
    """
    cnt_fatal = models.IntegerField(verbose_name='危急', default=0)
    cnt_high = models.IntegerField(verbose_name='高危', default=0)
    cnt_mid = models.IntegerField(verbose_name='中危', default=0)
    cnt_low = models.IntegerField(verbose_name='低危', default=0)
    total = models.IntegerField(verbose_name='合计', default=0)
    create_datetime = models.DateTimeField(verbose_name='创建时间')
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True, db_index=True)

    def total_count(self):
        return self.cnt_fatal + self.cnt_high + self.cnt_mid + self.cnt_low


class SkyEyeLog(models.Model):
    """
    天眼报警日志
    """
    attack_sip = models.CharField(verbose_name='攻击IP', max_length=32)
    sport = models.CharField(verbose_name='源端口', max_length=16)
    location = models.CharField(verbose_name='归属地', max_length=128, null=True)
    dip = models.CharField(verbose_name='目标IP', max_length=32)
    dport = models.CharField(verbose_name='目标端口', max_length=16)
    alarm_sip = models.CharField(verbose_name='受害IP', max_length=16, null=True)
    hazard_level_choices = (
        (0, '危急'),
        (1, '高危'),
        (2, '中危'),
        (3, '低危'),
    )
    hazard_level = models.SmallIntegerField(verbose_name='威胁级别', choices=hazard_level_choices)
    super_type_choices = (
        (1, 'APT事件'),
        (2, '攻击利用'),
        (3, '恶意软件'),
        (4, '拒绝服务'),
        (5, '侦察'),
        (6, '可疑活动'),
        (7, '策略'),
        (8, '系统'),
        (9, '应用程序'),
        (10, '认证'),
        (11, '网络访问'),
    )
    super_type = models.SmallIntegerField(verbose_name='告警类型', choices=super_type_choices)
    type = models.CharField(verbose_name='告警子类', max_length=32)
    name_type_chain = models.CharField(verbose_name='告警类型', max_length=64)
    threat_name = models.CharField(verbose_name='威胁名称', max_length=64)
    proto = models.CharField(verbose_name='协议', max_length=16, null=True)
    repeat_count = models.IntegerField(verbose_name='攻击次数')
    host_state_choices = (
        (1, '企图'),
        (2, '攻击成功'),
        (3, '失陷'),
        (4, '失败'),
    )
    host_state = models.SmallIntegerField(verbose_name='攻击结果', choices=host_state_choices)
    ioc = models.CharField(verbose_name='威胁情报', max_length=64)
    attack_dimension_choices = (
        (1, '横向攻击'),
        (2, '外联攻击'),
        (3, '外部攻击'),
    )
    attack_dimension = models.SmallIntegerField(verbose_name='攻击维度', choices=attack_dimension_choices)
    access_time = models.DateTimeField(verbose_name='最近发生时间')
    create_datetime = models.DateTimeField(verbose_name='创建时间')
